import axios from 'axios'
import { addPending, removePending } from './cancel'
import requestError from './error'

const service = axios.create({
  baseURL: process.env.VUE_APP_BASE_URL,
  timeout: 10000
})

// 接口这样设置post和put请求采用payload方式，而不是formdata
// headers: {
//   payload: 'payload'
// },
service.interceptors.request.use(
  (config) => {
    if (
      config.headers.payload
      && config.headers.payload !== 'payload'
      && (config.method === 'post' || config.method === 'put')
    ) {
      config.transformRequest = [
        (data) => {
          let ret = ''
          if (Object.prototype.toString.call(data) === '[object Object]' && Object.keys(data).length > 0) {
            Object.keys(data).forEach((item) => {
              ret += `${encodeURIComponent(item)}=${encodeURIComponent(
                data[item]
              )}&`
            })
          }
          return ret
        }
      ]
    }
    delete config.headers.payload
    // 将接口添加进待取消队列
    addPending(config)
    return config
  },
  (error) => {
    Promise.reject(error)
  }
)

service.interceptors.response.use(
  (response) => {
    const { config, data, status } = response
    const { code, message } = data
    removePending(config.url)
    // '000000' 海康接口成功标志
    if (status === 200 && (code === 200 || code === '000000')) {
      return data
    }
    // 二进制流
    if ((config.responseType === 'blob' || config.responseType === 'weather') && data) {
      return data
    }
    const errMsg = `请求异常:${JSON.stringify({ url: config.url, code, message })
      }`
    return Promise.reject(errMsg)
  },
  (error) => {
    const err = error
    if (axios.isCancel(error)) {
      // 接口被取消 返回不同的标志 页面可做出相应的处理
      err.cancel = true
    } else {
      // 接口报错
      err.error = true
      err.des = error?.response?.data?.message || requestError(error)
    }
    return Promise.reject(err)
  }
)

/**
 * @desc: 封装的请求函数 api文件里使用
 * @param {*} config
 */
const request = (config) => {
  let c = JSON.parse(JSON.stringify(config))
  if (c.this) {
    c = {
      ...c,
      ...c.this
    }
  }
  const method = c.method.toLowerCase()
  if (method === 'get' || method === 'delete') {
    c.params = c.data
  }
  return service(c)
}

export default request
